#ifndef CSERVER_COMMON_ARCHIVE_MEM_ARCHIVE_H__
#define CSERVER_COMMON_ARCHIVE_MEM_ARCHIVE_H__

#include <cserver/range.h>
#include <vector>


namespace csrv{ 
	const size_t unknow_size = size_t(-1);

	struct  buffer_in	// reader, random, const_view
	{
		typedef char* iterator;
		explicit buffer_in(const std::vector<char>& buf);
		explicit buffer_in(const range<const char*>& buf);

		range<char*> read(const range<char*>& buf);
		bool readable() const;

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);


		range<const char*> data() const;
	private:
		size_t m_pos;
		range<const char*> m_data;

	};

	struct  buffer_out	//  writer, random, view
	{
		typedef const char* const_iterator;
		explicit buffer_out(std::vector<char>& buf);

		range<const char*> write(const range<const char*>& r);
		size_t truncate(size_t size);
		bool writable() const;
		void sync() ;

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);

		std::vector<char> & data();
		const std::vector<char> & data() const;
	protected:
		size_t m_pos;
		std::vector<char>* m_data;
	};

	struct  buffer_io // reader, writer, random, const_view, view
	{
		typedef char* iterator;
		typedef const char* const_iterator;

		explicit buffer_io(std::vector<char>& buf);
		range<iterator> read(const range<char*>& buf);
		bool readable() const;

		range<const char*> write(const range<const char*>& r);
		size_t truncate(size_t size);
		bool writable() const;
		void sync() ;

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);

		std::vector<char> & data();
		const std::vector<char> & data() const;

		protected:
		size_t m_pos;
		std::vector<char>* m_data;
	};

	struct  fixed_buffer_io	//  writer, random, view
	{
		typedef char* iterator;
		typedef const char* const_iterator;
		explicit fixed_buffer_io(const range<char*>& buf);

		range<char*> read(const range<char*>& buf);
		bool readable() const;

		range<const char*> write(const range<const char*>& r);
		bool writable() const;
		void sync();

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);

		size_t truncate(size_t size);
		range<char*> data() const;
	private:
		size_t m_pos;
		range<char*> m_data;
	};

	typedef buffer_in mem_reader;

	struct  mem_writer : buffer_out
	{
		mem_writer();
        mem_writer(const mem_writer&);
        mem_writer(mem_writer&&);
        
        mem_writer& operator=(const mem_writer&);
        mem_writer& operator=(mem_writer&&);
        
		private:
		std::vector<char> m_data;
	};

	struct  mem_archive : buffer_io
	{
		mem_archive();
        mem_archive(mem_archive&&);
        mem_archive(const mem_archive&);
		explicit mem_archive(const std::vector<char>& buf);
        
        mem_archive& operator=(const mem_archive&);
        mem_archive& operator=(mem_archive&&);
        
		private:
		std::vector<char> m_data;
	};

	struct  zero{
		zero();
		range<char*> read(const range<char*>& buf);
		bool readable() const;

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);
		private:
		size_t m_pos;
	};
	struct  null{
		null();
		range<const char*> write(const range<const char*>& r);
		bool writable() const;
		void sync() ;

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);

		size_t truncate(size_t size);
		private:
		size_t m_pos;
	};

	struct  empty{
		range<char*> read(const range<char*>& buf);
		bool readable() const;

		size_t offset() const;
		size_t size() const;
		size_t seek(size_t offset);
	};

}

#endif //end CSERVER_COMMON_ARCHIVE_MEM_ARCHIVE_H__


